﻿namespace DCHealthCheck.MvcWeb.Classes.DataServices {

    #region Usings
    using DCHealthCheck.Common;
    using DCHealthCheck.DomainModel;
    using DCHealthCheck.MvcWeb.Classes.ViewModels;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Web; 
    #endregion

    public class DCDataService : BaseDataService, IDCDataService {

        #region Members
        private readonly IRepository<DomainController, IEntityManager> DCRepository;
        #endregion

        #region Constructor
        public DCDataService(IRepository<DomainController, IEntityManager> dcRepository) : base(dcRepository) {
            if (dcRepository == null) {
                throw new ArgumentNullException("dcRepository");
            }
                this.DCRepository = dcRepository;
        }
        #endregion

        #region Methods
        private IQueryable<DomainController> GetFilteredDomainControllers(DCViewModel viewModel) {

            var domainControllers = this.DCRepository.Get();

            if (!string.IsNullOrWhiteSpace(viewModel.Domain)) {
                domainControllers = domainControllers.Where(x => x.NetbiosDomain == viewModel.Domain);
            }

            if (!string.IsNullOrWhiteSpace(viewModel.ADSite)) {
                domainControllers = domainControllers.Where(x => x.ADSite == viewModel.ADSite);
            }

            if (!string.IsNullOrWhiteSpace(viewModel.OSVersion)) {
                domainControllers = domainControllers.Where(x => x.OSVersion == viewModel.OSVersion);
            }

            if (!string.IsNullOrWhiteSpace(viewModel.DCName)) {
                domainControllers = domainControllers.Where(x => x.SamAccountName.ToUpper().Contains(viewModel.DCName.ToUpper()));
            }

            return domainControllers;
        }        

        public void ProcessData(DCViewModel viewModel) {
            Global.DefaultLog.DebugFormat("[ThreadId: {0}] {1}", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());

            if (viewModel == null) {
                throw new ArgumentNullException("viewModel");
            }

            try {
                viewModel.Initialize();
                var domainControllers = this.GetFilteredDomainControllers(viewModel);
                viewModel.DisplayTotalResults = domainControllers.Count();

                #region Skip count, take, and sorting
                if (!string.IsNullOrWhiteSpace(viewModel.SortColumn)) {
                    if (viewModel.CurrentSortDirection == System.Web.Helpers.SortDirection.Ascending) {
                        viewModel.DomainControllers = domainControllers
                            .OrderBy(viewModel.SortColumn)
                            .Skip(viewModel.SkipCount.Value)
                            .Take(viewModel.TakeCount.Value)
                            .ToList();
                    }
                    else {
                        viewModel.DomainControllers = domainControllers
                            .OrderByDescending(viewModel.SortColumn)
                            .Skip(viewModel.SkipCount.Value)
                            .Take(viewModel.TakeCount.Value)
                            .ToList();
                    }
                }
                else {
                    viewModel.DomainControllers = domainControllers
                        .OrderBy(x => x.SamAccountName)
                        .Skip(viewModel.SkipCount.Value)
                        .Take(viewModel.TakeCount.Value)
                        .ToList();
                }
                #endregion

                viewModel.GetPageCounts();
                var filteredDCIds = this.GetFilteredDomainControllers(viewModel)
                    .Select(x => x.Id)
                    .Distinct()
                    .ToList();
                this.BuildFilterSelectLists(filteredDCIds, viewModel);
            }
            catch (Exception e) {
                Global.DefaultLog.DebugFormat("[ThreadId: {0}] {1} {2}", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName(), e.VerboseExceptionString());
            }
        }
        #endregion
    }
}